/*
 * topological-hex, a program to compute combinatorial hexahedral meshes.
 *
 * Copyright (C) <2018> <Université catholique de Louvain (UCL), Belgique>
 *
 * List of the contributors to the development, description and complete
 * License: see LICENSE file.
 *
 * This program (topological-hex) is free software:
 * you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see COPYING file).  If not,
 * see <http://www.gnu.org/licenses/>.
 */

#ifndef MESH_H_
#define MESH_H_

#include <stdint.h>

#include "types.h"
#include "utils.h"

/**
 * @defgroup mesh Mesh
 *
 * Data structure and basic operations to manipulate a mesh.
 */

/**
 * @addtogroup mesh
 * @{
 */

typedef struct mesh {
  uint32_t num_vertices;

  /**
   * Array containing the coordinates of each vertex. 4 values per element, the
   * fourth of which being unused.
   */
  ALIGNED double *vertices;

  /**
   * Number of quads on the boundary.
   */
  uint32_t num_boundary_quads;

  /**
   * Total number of quads. This includes @ref mesh::num_boundary_quads.
   */
  uint32_t num_quads;

  /**
   * Indices of the vertices of each quad.
   */
  ALIGNED vertex_index *quads;

  uint32_t num_hexes;

  /**
   * Indices of the vertices of each quad.
   */
  ALIGNED vertex_index *hexes;

  /**
   * Representation of the adjacency of all hexahedra within the mesh.
   *
   * The hexahedron referenced at index 6*i + j of this array is adjacent to
   * hexahedron i
   */
  ALIGNED hex_index *hex_adjacency;

  /**
   * Index of the quads corresponding to facets of hexahedron.
   */
  ALIGNED quad_index *hex_facets;
} mesh;

/**
 * Initializes a mesh to be empty.
 *
 * Calling this function is not necessary when using @ref mesh_load.
 */
void mesh_init(mesh *mesh);

/**
 * Loads a mesh from a file.
 *
 * The contents of the mesh data structure do not need to be initialized when
 * this function is called.
 */
error_code mesh_load(mesh *mesh, const char *path);

error_code save_mesh(mesh *mesh, const char *filename);

/**
 * Reserves space for a certain number of hexahedra within the mesh.
 *
 * This function can only be used to increase the total number of hexahedra. It
 * also does not remove existing data from the mesh.
 *
 * This function should be called on an initialized mesh. It uses the number of
 * quads in the boundary to determine how much memory should be allocated to
 * store data about quads.
 */
error_code mesh_reserve(mesh *mesh, uint32_t num_hexes);

/**
 * Releases all memory used to store a mesh.
 */
void mesh_release(mesh *mesh);

/**
 * Returns the number of vertices on the boundary of the mesh.
 *
 * This operation only works if all vertices on this boundary are numbered from
 * 0 to n without gaps.
 */
uint32_t mesh_num_boundary_vertices(const mesh *mesh);

/**
 * @}
 */

#endif
